﻿#region Copyright(c) 2006 ZO, All right reserved.
// -----------------------------------------------------------------------------
// Copyright(c) 2006 ZO, All right reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   1.  Redistribution of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//   2.  Redistribution in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//   3.  The name of the author may not be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// -----------------------------------------------------------------------------
#endregion


#region Using directives

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

#endregion

namespace ZO.SmartCore.Windows.Forms
{
    /// <summary>
    /// Base Class For Notification pop-ups Form, Much like MSN email notification pop-ups
    /// </summary>
    public class SmartNotifyForm : SmartForm
    {

        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="SmartNotifyForm"/> class.
        /// </summary>
        public SmartNotifyForm() : this(false)
        {
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SmartNotifyForm"/> class.
        /// </summary>
        /// <param name="dropShadow">if set to <see langword="true"/> [drop shadow].</param>
        public SmartNotifyForm(bool dropShadow)
            : base(dropShadow)
        {
            this.InitializeComponent();

        }
        #endregion

        #region Destructor
        /// <summary>
        /// Releases unmanaged resources and performs other cleanup operations before the
        /// <see cref="SmartNotifyForm"/> is reclaimed by garbage collection.
        /// </summary>
        ~SmartNotifyForm()
        {
            this.Closing -= new CancelEventHandler(this.NotifyForm_Closing);

        }

        #endregion

        #region Fields
        private Timer NotifyTimer;
        private IContainer components;

        private bool showing;
        private bool forceClose;
        private DialogResult originalDialogResult;

        private NotifyStyle _Style = NotifyStyle.Slide;


        private int defaultTop;
        private double incrementValue;
        private int screenHeight;
        #endregion

        #region Events
        /// <summary>
        /// Occurs When Form is fully displayed on screen
        /// </summary>
        public event EventHandler Displayed;
        #endregion

        #region Operators

        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the style of the notify window.
        /// </summary>
        /// <value>The style.</value>
        public NotifyStyle Style
        {
            get { return _Style; }
            set { _Style = value; }
        }
        #endregion

        #region Methods
      
        /// <summary>
        /// Initializes the component.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new Container();
            this.NotifyTimer = new Timer(this.components);
            this.SuspendLayout();
            // 
            // NotifyTimer
            // 
            this.NotifyTimer.Tick += new EventHandler(this.NotifyTimer_Tick);
            // 
            // NotifyForm
            // 
            this.ClientSize = new Size(292, 266);
            this.DropShadow = true;
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            this.Name = "SmartNotifyForm";
            this.ShowInTaskbar = false;
            this.Text = "Notifier Window";
            this.Closing += new CancelEventHandler(this.NotifyForm_Closing);
            this.Load += new EventHandler(this.NotifyForm_Load);
            this.ResumeLayout(false);

        }

        /// <summary>
        /// Handles the Closing event of the NotifyForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:System.ComponentModel.CancelEventArgs"/> instance containing the event data.</param>
        void NotifyForm_Closing(object sender, CancelEventArgs e)
        {
            if (!forceClose)
            {
                originalDialogResult = this.DialogResult;
                e.Cancel = true;
                showing = false;
                NotifyTimer.Start();
            }
            else
            {
                this.NotifyTimer.Dispose();
                this.DialogResult = originalDialogResult;
            }
        }

        /// <summary>
        /// Handles the Load event of the NotifyForm control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
        private void NotifyForm_Load(object sender, EventArgs e)
        {
            if (!this.DesignMode)
            {


                int screenWidth = Screen.PrimaryScreen.WorkingArea.Width;
                screenHeight = Screen.PrimaryScreen.WorkingArea.Height;

                switch (this.Style)
                {
                    case NotifyStyle.Slide:
                        this.Left = screenWidth - this.Width - 5;
                        defaultTop = screenHeight - this.Height - 1;
                        this.Top = screenHeight;
                        incrementValue = (screenHeight - defaultTop) % (this.Height / 10);

                        break;

                    case NotifyStyle.Fade:
                        this.Opacity = 0.0;
                        this.Left = screenWidth - this.Width - 5;
                        this.Top = screenHeight - this.Height - 1;
                        incrementValue = 0.1;
                        break;

                }

                showing = true;

                NotifyTimer.Start();
            }
        }
        #endregion

        /// <summary>
        /// Handles the Tick event of the NotifyTimer control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
        private void NotifyTimer_Tick(object sender, EventArgs e)
        {
            if (showing)
            {
                switch (this.Style)
                {
                    case NotifyStyle.Slide:
                        if (this.Top > defaultTop)
                        {
                            this.Top -= (int)incrementValue;
                        }
                        else
                        {
                            this.OnDisplayed(EventArgs.Empty);
                            showing = false;
                            NotifyTimer.Stop();
                        }

                        break;
                    case NotifyStyle.Fade:
                        if (this.Opacity < 1)
                        {
                            this.Opacity += incrementValue;
                        }
                        else
                        {
                            this.OnDisplayed(EventArgs.Empty);
                            showing = false;
                            NotifyTimer.Stop();
                        } break;
                }


            }
            else
            {
                switch (this.Style)
                {
                    case NotifyStyle.Slide:
                        if (this.Top < screenHeight)
                        {
                            this.Top += (int)incrementValue;
                        }
                        else
                        {
                            showing = false;
                            NotifyTimer.Stop();
                            forceClose = true;
                            this.Close();
                        }

                        break;

                    case NotifyStyle.Fade:
                        if (this.Opacity > 0)
                        {
                            this.Opacity -= incrementValue;
                        }
                        else
                        {
                            showing = false;
                            NotifyTimer.Stop();
                            forceClose = true;
                            this.Close();
                        } break;
                }


            }
        }


        /// <summary>
        /// Raises the <see cref="Displayed"/> event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
        protected virtual void OnDisplayed(EventArgs e)
        {
            if (this.Displayed != null)
            {
                this.Displayed(this, e);
            }
        }


        /// <summary>
        /// Raises the <see cref="E:System.Windows.Forms.Control.MouseEnter"></see> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"></see> that contains the event data.</param>
        protected override void OnMouseEnter(EventArgs e)
        {
            this.NotifyTimer.Stop();

            showing = true;

            NotifyTimer.Start();

            base.OnMouseEnter(e);
        }
    }
}
